#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>

int main() {
    // 创建两个管道
    std::array<int, 2> pipefds1, pipefds2;
    pipe(pipefds1.data());  // 创建第一个管道
    pipe(pipefds2.data());  // 创建第二个管道

    // 向管道写入数据
    write(pipefds1[1], "Hello", 5);  // 写入数据到第一个管道
    write(pipefds2[1], "World", 5);  // 写入数据到第二个管道

    fd_set readfds; // 文件描述符集合，用于select调用
    struct timeval timeout; // 时间结构体，用于设置超时
    int ret, fd_max; // 用于存储select的返回值和文件描述符的最大值

    while (true) {
        FD_ZERO(&readfds);  // 清空文件描述符集
        FD_SET(pipefds1[0], &readfds);  // 将pipefds1[0]加入读集合
        FD_SET(pipefds2[0], &readfds);  // 将pipefds2[0]加入读集合

        // 计算最大的文件描述符
        fd_max = std::max(pipefds1[0], pipefds2[0]);

        // 设置超时时间为5秒
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        // 调用select等待文件描述符准备好或超时
        ret = select(fd_max + 1, &readfds, nullptr, nullptr, &timeout);

        if (ret == -1) {
            perror("select");  // select调用失败
            exit(EXIT_FAILURE);
        } else if (ret == 0) {
            std::cout << "Timeout!" << std::endl;  // select超时
            break;
        } else {
            // 检查文件描述符是否准备好并读取数据
            if (FD_ISSET(pipefds1[0], &readfds)) {
                char buf[6];
                read(pipefds1[0], buf, 5);  // 从pipefds1[0]读取数据
                buf[5] = '\0';
                std::cout << "Data from pipe1: " << buf << std::endl;
            }
            if (FD_ISSET(pipefds2[0], &readfds)) {
                char buf[6];
                read(pipefds2[0], buf, 5);  // 从pipefds2[0]读取数据
                buf[5] = '\0';
                std::cout << "Data from pipe2: " << buf << std::endl;
            }
            break;
        }
    }

    // 关闭管道文件描述符
    close(pipefds1[0]);
    close(pipefds1[1]);
    close(pipefds2[0]);
    close(pipefds2[1]);

    return 0;
}
